﻿// From http://www.switchonthecode.com/tutorials/wpf-tutorial-creating-a-custom-panel-control

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace ScrumTable.UI.View.CustomControl
{
    /// <summary>
    /// A StackPanel which is animated. AddedElements are moved inside and if positioning changes
    /// it will happen through a animation.
    /// </summary>
    public class StackPanelAnimated : StackPanel
    {

        private readonly TimeSpan _animationLength = TimeSpan.FromMilliseconds(400);
        public bool AnimateFromBottom { get; set; }
        protected override Size ArrangeOverride(Size finalSize)
        {

          if (Children == null || Children.Count == 0)
                return finalSize;

            TranslateTransform trans;
            double curX = 0, curY = 0, curLineHeight = 0;

            foreach (UIElement child in Children)
            {
                trans = child.RenderTransform as TranslateTransform;
                if (trans == null)
                {
                    child.RenderTransformOrigin = new Point(0, 0);

                    if (AnimateFromBottom)
                    {
                        trans = new TranslateTransform() {Y = finalSize.Height};
                    }
                    else
                    {
                        trans = new TranslateTransform();    
                    }
                    
                    child.RenderTransform = trans;
                }

                if (curX + child.DesiredSize.Width > finalSize.Width)
                { //Wrap to next line
                    curY += curLineHeight;
                    curX = 0;
                    curLineHeight = 0;
                }

                if (Orientation == Orientation.Horizontal)
                {
                    child.Arrange(new Rect(0, 0, child.DesiredSize.Width, finalSize.Height));
                }
                else
                {
                    child.Arrange(new Rect(0, 0, finalSize.Width, child.DesiredSize.Height));
                }

                if (curX != trans.X || curY != trans.Y)
                {
                    trans.BeginAnimation(TranslateTransform.XProperty, new DoubleAnimation(curX, _animationLength),
                                         HandoffBehavior.Compose);
                    trans.BeginAnimation(TranslateTransform.YProperty, new DoubleAnimation(curY, _animationLength),
                                         HandoffBehavior.Compose);
                }

                curX += child.DesiredSize.Width;
                if (child.DesiredSize.Height > curLineHeight)
                    curLineHeight = child.DesiredSize.Height;
            }

            //return base.ArrangeOverride(finalSize);
            return finalSize;
        }
    }


    /// <summary>
    /// A StackPanel which is animated. AddedElements are moved inside and if positioning changes
    /// it will happen through a animation.
    /// </summary>
    public class StackPanelAnimated2 : StackPanel
    {

        private readonly TimeSpan _animationLength = TimeSpan.FromMilliseconds(400);
    
        protected override Size ArrangeOverride(Size finalSize)
        {

            if (Children == null || Children.Count == 0)
                return finalSize;

            if( Orientation == Orientation.Horizontal)
            {
                throw new NotImplementedException();
            }

            TranslateTransform trans;
            double curY = 0, maxWidth = 0;
            
            foreach(UIElement child in Children)
            {
                if(child.IsMeasureValid)
                {
                    child.Measure(finalSize);
                    maxWidth = maxWidth > child.DesiredSize.Width ? maxWidth : child.DesiredSize.Width;
                }
            }
            foreach (Control child in Children)
            {
                trans = child.RenderTransform as TranslateTransform;
                if (trans == null)
                {
                     child.RenderTransformOrigin = new Point(0, 0);
                    trans = new TranslateTransform();
                    child.RenderTransform = trans;
                }

                double minMaxWidth = finalSize.Width - 10;

                child.Arrange(new Rect(0, 0, minMaxWidth, child.DesiredSize.Height));
                child.MaxWidth = minMaxWidth;
                child.MinWidth = minMaxWidth;
                if (Math.Abs(curY - trans.Y) > 0.1)
                {
                    trans.BeginAnimation(TranslateTransform.YProperty, new DoubleAnimation(curY, _animationLength),
                                         HandoffBehavior.Compose);
                }
                curY += 40;
                
            }
            
            

            //return base.ArrangeOverride(finalSize);
            return finalSize;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            if (Children == null || Children.Count == 0 || double.IsNaN(constraint.Width) || double.IsInfinity(constraint.Width))
                return new Size(0,0);
            Children[0].Measure(constraint);
            return new Size(constraint.Width, Children[0].DesiredSize.Height + (Children.Count-1) * 40);

        }
    }
}
